package com.yugao.fintech.libra.shortlink.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yugao.fintech.libra.shortlink.assembly.AccessLogAssembly;
import com.yugao.fintech.libra.shortlink.manager.SlLinkDomainManager;
import com.yugao.fintech.libra.shortlink.manager.SlLinkGroupManager;
import com.yugao.fintech.libra.shortlink.mapper.SlAccessLogMapper;
import com.yugao.fintech.libra.shortlink.model.entity.AccessLog;
import com.yugao.fintech.libra.shortlink.model.entity.LinkDomain;
import com.yugao.fintech.libra.shortlink.model.entity.LinkGroup;
import com.yugao.fintech.libra.shortlink.model.rqrs.AccessLogBasePageReq;
import com.yugao.fintech.libra.shortlink.model.rqrs.AccessLogResp;
import com.yugao.fintech.libra.shortlink.service.AccessLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 短链访问日志
 */
@Slf4j
@Service
public class AccessLogServiceImpl extends ServiceImpl<SlAccessLogMapper, AccessLog> implements IService<AccessLog>, AccessLogService {
    @Autowired
    private SlLinkGroupManager linkGroupManager;
    @Autowired
    private AccessLogAssembly accessLogAssembly;
    @Autowired
    private SlLinkDomainManager linkDomainManager;

    /**
     * 分页查询 短链访问日志
     *
     * @return 返回分页数据
     */
    @Override
    public IPage<AccessLogResp> pageAccessLog(AccessLogBasePageReq req) {
        LocalDateTime beginTime = req.getBeginLocalDateTime();
        LocalDateTime endTime = req.getEndLocalDateTime();
        LambdaQueryWrapper<AccessLog> queryWrapper = AccessLog.lqw()
            .eq(StrUtil.isNotEmpty(req.getCode()), AccessLog::getCode, req.getCode())
            .eq(Objects.nonNull(req.getGroupId()), AccessLog::getGroupId, req.getGroupId())
            .ge(Objects.nonNull(beginTime), AccessLog::getCreatedAt, beginTime)
            .le(Objects.nonNull(endTime), AccessLog::getCreatedAt, endTime)
            .orderByDesc(AccessLog::getCreatedAt);

        IPage<AccessLog> pageData = this.page(PageUtil.to(req), queryWrapper);
        Set<Long> domainIds = pageData.getRecords().stream().map(AccessLog::getDomainId).collect(Collectors.toSet());
        Set<Long> groupIds = pageData.getRecords().stream().map(AccessLog::getGroupId).collect(Collectors.toSet());
        groupIds.add(-1L);
        domainIds.add(-1L);

        Map<Long, LinkGroup> groupMap = linkGroupManager.listByIds(groupIds).stream()
                .collect(Collectors.toMap(LinkGroup::getId, Function.identity()));

        Map<Long, LinkDomain> domainMap = linkDomainManager.listByIds(domainIds).stream()
                .collect(Collectors.toMap(LinkDomain::getId, Function.identity()));

        return PageUtil.to(pageData, (e) -> {
            AccessLogResp rs = accessLogAssembly.toAccessLogResp(e);
            rs.setGroupName(Optional.ofNullable(groupMap.get(e.getGroupId())).map(LinkGroup::getName).orElse(""));
            String domain = Optional.ofNullable(domainMap.get(e.getDomainId())).map(LinkDomain::getDomain).orElse("");
            rs.setShortUrl(UrlUtils.removeRepeatSlashOfUrl(domain + "/" + e.getCode()));
            return rs;
        });
    }

    /**
     * 保存 短链访问日志
     *
     * @param entity 新增的记录
     * @return 返回影响行数
     */
    @Override
    public boolean saveAccessLog(AccessLog entity) {
    	return this.save(entity);
    }
    
    /**
     * 通过ids删除 短链访问日志
     *
     * @param ids 删除的主键
     * @return 返回影响行数
     */
    @Override
    public boolean deleteAccessLogByIds(List<Long> ids) {
    	return this.removeByIds(ids);
    }
}
